/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.dataconverter.reader;

import br.dataconverter.util.DataColumn;
import br.dataconverter.util.DataType;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;

/**
 * Esta interface define o conjunto básico de métodos que um leitor de dados
 * (@DataReader) deve oferecer.
 *
 * Um cenário normal no uso do leitor deveria passar pela seguinte sequência de
 * invocações:
 *
 * <ul>
 * <li> setFile(file);
 * <li> setColumnsHeader(true) ou setColumnsHeader(false)
 * <li> getColunsNames()
 * </ul>
 *
 *
 * @author Ronen Filho
 */

public interface DataReader {

	/*
     +setFile(File:file):void
     +setColumnsHeader(boolean header):void
     +isColumnsHeader():boolean
     +getColumnsNames():List<String>
     +setColumnsFilter(List<String> columnsNames):void
     +setColumnsFilter(int[] columnsIndex):void
     +getColumns():List<DataColumn>
     */
	
    /**
     * Este método especifica qual será o arquivo de entrada a ser processado.
     *
     * @param file uma referência a um arquivo válido. Caso seja fornecida uma
     * referência inválida (null), nada é alterado.
     */
    public void setFile(File file);


    /**
     * Este método configura seta o atributo que determina se o arquivo de
     * entrada possui ou não uma linha de cabeçalho.
     *
     * @param header se o valor for true assume-se que a primeira linha do
     * arquivo é uma linha de cabeçalho. Caso seja false assume-se que o arquivo
     * não contém linha de cabeçalho.
     */
    public void setColumnsHeader(boolean header);

    /**
     * Este método permite apenas consultar se o atributo que indica se o
     * arquivo contém linha de cabeçalho foi setado.
     *
     * @return true caso o arquivo contenha linha de cabeçalho ou false caso não
     * contenha. Observa-se que quem define se o arquivo contém ou não linha de
     * cabeçalho é o próprio usuário por meio da invocação do método
     * {@link #setColumnsHeader(boolean)}.
     */
    public boolean isColumnsHeader();

    /**
     * Este método permite consultar os nomes das colunas do arquivo de entrada
     * de dados.
     *
     * Observa-se que o nome das colunas existe apenas caso o arquivo contenha
     * uma linha de cabeçalho. Do contrário o método retorna uma lista com os
     * strings "0", "1", ..., "n-1", sendo n total de colunas do arquivo de
     * entrada.
     *
     * @return lista contendo os nomes das colunas do arquivo de entrada de
     * dados ou uma lista numerada de 0 a n-1 sendo n o número de colunas do
     * arquivo de entrada.
     *
     * @throws IOException caso aconteça algum problema na leitura ou acesso ao
     * arquivo.
     */
    public List<String> getColumnsNames() throws FileNotFoundException, IOException;

    /**
     * Este método define o nome e a ordem das colunas que devem ser convertidas
     * no arquivo de saída.
     *
     * Caso esse método não seja invocado assume-se que todas as colunas, na
     * ordem em que aparecem no arquivo de entrada, devem ser utilizadas.
     *
     * Observa-se que se o atributo que determina que o arquivo contém linhas de
     * cabeçalho for true esse é o método que deve ser utilizado para se
     * especificar quais colunas devem ser exportadas. Do contrário, o usuário
     * deve definir as colunas e a ordem por meio do método
     * {@link #setColumnsFilter(int[])}
     *
     * @param columnsName lista com o nome e ordem das colunas que devem ser
     * convertidas no arquivo de saída.
     */
    public void setColumnsFilter(List<String> columnsName);

    /**
     * Este método define o número e a ordem das colunas que devem ser
     * convertidas no arquivo de saída.
     *
     * Os índices inicial de 0 e vão até n-1, sendo n o número total de colunas
     * do arquivo de entrada.
     *
     * Caso esse método não seja invocado assume-se que todas as colunas, na
     * ordem em que aparecem no arquivo de entrada, devem ser utilizadas.
     *
     * Observa-se que se o atributo que determina que o arquivo contém linhas de
     * cabeçalho for false esse é o método que deve ser utilizado para se
     * especificar quais colunas devem ser exportadas. Do contrário, o usuário
     * deve definir as colunas e a ordem por meio do método
     * {@link #setColumnsFilter(java.util.List)}.
     *
     * @param columnsIndex vetor com índices e ordem das colunas que devem ser
     * convertidas no arquivo de saída. Índices válidos estão no intervalo de 0
     * a n-1, sendo n o número total de colunas do arquivo de entrada.
     */
    public void setColumnsFilter(int[] columnsIndex);

    /**
     * Este método especifica qual o tipo de dado de cada coluna do arquivo de
     * entrada.
     *
     * Caso não sejam definidos os tipos de dados assume-se que todos devem ser
     * tratados como {@link java.lang.String}.
     *
     * Os tipos aceitos estão definidos na classe
     * {@link br.dataconverter.util.DataType}.
     *
     * @param dataType lista com os tipos de dados de cada coluna do arquivo de
     * entrada a ser manipulada. Os tipos devem respeitar a mesma ordem
     * definidas nos métodos {@link #setColumnsFilter(java.util.List)} ou
     * {@link #setColumnsFilter(int[])}.
     */
    public void setColumnsDataType(List<DataType> dataType);
    
    /**
     * Este método permite o acesso aos dados de interesse do arquivo de
     * entrada, sendo cada coluna representada por um objeto do tipo
     * {@link br.dataconverter.util.DataColumn}.
     *
     * Se nenhum dos métodos {@link #setColumnsFilter(java.util.List)} ou
     * {@link #setColumnsFilter(int[])} foi invocado assume-se que todos os
     * dados do arquivo de entrada devem ser extraídos. Do contrário, esse
     * método devolve apenas as colunas especificadas nos filtros.
     *
     * @return uma lista de {@link br.dataconverter.util.DataColumn} sendo que
     * cada coluna representa uma coluna de dados do arquivo de entrada.
     */
    public List<DataColumn> getColumns() throws FileNotFoundException, IOException;
    //public List<String> getColumns() throws FileNotFoundException, IOException;
    
}
